home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / term / tpic.trm < prev    next >
Text File  |  1993-09-15  |  26KB  |  958 lines

  1. /*
  2.  * $Id: tpic.trm%v 3.50 1993/07/09 05:35:24 woo Exp $
  3.  */
  4.  
  5. /* GNUPLOT - tpic.trm */
  6. /*
  7.  * Copyright (C) 1990 - 1993   
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted, 
  11.  * provided that the above copyright notice appear in all copies and 
  12.  * that both that copyright notice and this permission notice appear 
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the modified code.  Modifications are to be distributed 
  17.  * as patches to released version.
  18.  *  
  19.  * This software  is provided "as is" without express or implied warranty.
  20.  * 
  21.  * This file is included by ../term.c.
  22.  *
  23.  * This terminal driver supports:
  24.  *   The tpic \specials (version 2.2) for LaTeX. 
  25.  *
  26.  * AUTHORS
  27.  *   Oh-Yeah?   3 Sep. 1992 (closely following eepic.trm by David Kotz)
  28.  *   A. Woo     5 Oct. 1992 (removed ansi prototypes for braindead compilers)
  29.  *
  30.  * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
  31.  * 
  32.  */
  33. /*
  34.  *  This file contains the tpic terminal driver for use with LaTeX. 
  35.  *  This is an alternative to the latex and eepic drivers. You need 
  36.  *  a printer driver that supports the tpic \specials version 2.2.
  37.  *
  38.  * Comparison with the eepic driver (eepic.trm):
  39.  *  Merits
  40.  *    - More point and line types
  41.  *    - Options to change point size, linewidth, dot & dash intervals
  42.  *    - Dotted and dashed lines for high-sample-rate curves (but may
  43.  *      depend on tpic (da & dt) implementation of your dvi driver :-)
  44.  *    - Overlapped points made fancier by tpic shading facility
  45.  *    - Optional comments for trimming figure margins
  46.  *    - No need for epic and eepic macros
  47.  *  Drawback
  48.  *    - You cannot use eepicemu macro for non-tpic-support dvi drivers
  49.  *
  50.  * LATEX must also be defined.
  51.  */
  52.  
  53.  
  54. /* These parameters can be modified as you like, through options.  Say 
  55.    "set terminal tpic <pointsize> <linewidth> <interval>".  <pointsize> 
  56.    and <linewidth> are integers in milli-inches; <interval> is a float 
  57.    in inches.  If non-positive value is specified, the default (below) 
  58.    is chosen. 
  59. */
  60. static int tpic_pointsize   =  40; /* min point radius   (in milli-inches) */
  61. static int tpic_linewidth   =   6; /* min line thickness (in milli-inches) */
  62. static double tpic_interval = 0.1; /* min dot & dash intervals (in inches) */
  63.  
  64. /* ARROWS: same code as for LATEX */
  65. /* static void best\_latex\_arrow(int sx, int sy, int ex, int ey, int who, 
  66.     TBOOLEAN head); figure out the best arrow. in latex.trm */
  67. static void best_latex_arrow();
  68.  
  69. /* all prototypes ... */
  70. int TPIC_options(); /* get size options */
  71. int TPIC_init();
  72. int TPIC_reset();
  73. int TPIC_text();
  74. /* TBOOLEAN TPIC_scale(double xs, double ys);  scaling factors */
  75. TBOOLEAN TPIC_scale();
  76. int TPIC_graphics();
  77. /* int TPIC_move(unsigned int x, unsigned int y);
  78. int TPIC_vector(unsigned int ux, unsigned int uy); */
  79. int TPIC_move();
  80. int TPIC_vector();
  81. static void tpic_startline();  /* private */
  82. static void tpic_endline();  /* private */
  83. /* static void tpic_pushpath(unsigned int x, unsigned int y); /* private */
  84. static void tpic_pushpath();
  85. static void tpic_scanpath();
  86. /* int TPIC_linetype(int linetype);
  87. int TPIC_put_text(int x, int y, char *str); /* ref point and text */
  88. int TPIC_linetype();
  89. int TPIC_put_text();
  90. /* TBOOLEAN TPIC_text_angle(int angle);
  91. TBOOLEAN TPIC_justify_text(enum JUSTIFY mode); */
  92. TBOOLEAN TPIC_text_angle();
  93. TBOOLEAN TPIC_justify_text();
  94. /* int TPIC_point(unsigned int x, unsigned int y, int number); */
  95. int TPIC_point();
  96. /* int TPIC_arrow(int sx, int sy, int ex, int ey, TBOOLEAN head); */
  97. int TPIC_arrow();
  98. /* void tpic_diamond(int size); */
  99. void tpic_diamond();
  100. /* void tpic_plus(int size); */
  101. void tpic_plus();
  102. /* void tpic_box(int size); */
  103. void tpic_box();
  104. /* void tpic_times(int size); */
  105. void tpic_times();
  106. /* void tpic_triangle(int size); */
  107. void tpic_triangle();
  108. /* void tpic_star(int size); */
  109. void tpic_star();
  110. /* void tpic_hexagon(int size); */
  111. void tpic_hexagon();
  112. /* void tpic_circle(int size); */
  113. void tpic_circle();
  114. /* void tpic_doublecircle(int size); */
  115. void tpic_doublecircle();
  116. /* void tpic_vercircle(int size); /* circle with | */
  117. void tpic_vercircle(); /* circle with | */
  118. /* void tpic_horcircle(int size); /* circle with - */
  119. void tpic_horcircle(); /* circle with - */
  120. /* void tpic_pluscircle(int size); /* circle with + */
  121. void tpic_pluscircle(); /* circle with + */
  122. /* void tpic_timescircle(int size); /* circle with times */
  123. void tpic_timescircle(); /* circle with times */
  124. /* void tpic_starcircle(int size); /* circle with star */
  125. void tpic_starcircle(); /* circle with star */
  126. /* void tpic_dotcircle(int size); /* circle with dot (black circle) */
  127. void tpic_dotcircle(); /* circle with dot (black circle) */
  128. /* void tpic_diamondcircle(int size); /* circle with black diamond */
  129. void tpic_diamondcircle(); /* circle with black diamond */
  130. /* void tpic_boxcircle(int size); /* circle with black box */
  131. void tpic_boxcircle(); /* circle with black box */
  132. /* void tpic_trianglecircle(int size); /* circle with black triangle */
  133. void tpic_trianglecircle(); /* circle with black triangle */
  134. /* void tpic_hexagoncircle(int size); /* circle with black hexagon */
  135. void tpic_hexagoncircle(); /* circle with black hexagon */
  136. /* void tpic_plustimescircle(int size); /* no more idea ... with plus & times */
  137. void tpic_plustimescircle(); /* no more idea ... with plus & times */
  138. /* void tpic_abspath(unsigned int x, unsigned int y); /* absolute coord */
  139. void tpic_abspath(); /* absolute coord */
  140. /* void tpic_path(int x, int y); */
  141. void tpic_path();
  142. /* void tpic_flush(void); */
  143. void tpic_flush();
  144. /* void tpic_arc(int radius); /* actually, draw a full circle */
  145. void tpic_arc(); /* actually, draw a full circle */
  146. /* void tpic_shade(double grayscale); */
  147. void tpic_shade();
  148. /* void tpic_pen(int thickness); */
  149. void tpic_pen();
  150. /* void tpic_dottedflush(double interval); */
  151. void tpic_dottedflush();
  152. /* void tpic_dashedflush(double interval); */
  153. void tpic_dashedflush();
  154.  
  155. #define TPIC_UNIT 0.001 /* tpic \specials unit in inches (1 milli-inch) */
  156. /* 5 inches wide by 3 inches high (default) */
  157. #define TPIC_XMAX (unsigned int) (5 / TPIC_UNIT)
  158. #define TPIC_YMAX (unsigned int) (3 / TPIC_UNIT)
  159. #define TPIC_PTS_PER_UNIT (72.27 * TPIC_UNIT)
  160. #define TPIC_HTIC  (unsigned int) ( 5.0 / TPIC_PTS_PER_UNIT) /* 5pt */
  161. #define TPIC_VTIC  (unsigned int) ( 5.0 / TPIC_PTS_PER_UNIT) /* 5pt */
  162. #define TPIC_HCHAR (unsigned int) ( 5.3 / TPIC_PTS_PER_UNIT) /* 5.3pt */
  163. #define TPIC_VCHAR (unsigned int) (11.0 / TPIC_PTS_PER_UNIT) /* 11pt */
  164.  
  165. typedef enum {tpic_none, tpic_white, tpic_gray, tpic_black} tpic_shadestyle;
  166. typedef enum {tpic_nosize, tpic_small, tpic_medium, tpic_large} tpic_size;
  167. /* typedef void (*tpic_function)(int size); */
  168. typedef void (*tpic_function)();
  169. typedef struct {
  170.     tpic_shadestyle shadestyle;
  171.     tpic_size size;
  172.     tpic_function function;
  173. } tpic_point_info;
  174.  
  175. /* POINTS */
  176. static GPFAR tpic_point_info GPFAR tpic_point[] = {
  177.     {tpic_white, tpic_medium, tpic_diamond},
  178.     {tpic_none,  tpic_medium, tpic_plus},
  179.     {tpic_white, tpic_medium, tpic_box},
  180.     {tpic_none,  tpic_medium, tpic_times},
  181.     {tpic_white, tpic_medium, tpic_triangle},
  182.     {tpic_none,  tpic_medium, tpic_star},
  183.     {tpic_white, tpic_small,  tpic_circle},
  184.     {tpic_white, tpic_medium, tpic_circle},
  185.     {tpic_white, tpic_large,  tpic_circle},
  186.     {tpic_black, tpic_small,  tpic_circle},
  187.     {tpic_black, tpic_medium, tpic_circle},
  188.     {tpic_black, tpic_large,  tpic_circle},
  189.     {tpic_black, tpic_medium, tpic_diamond},
  190.     {tpic_black, tpic_medium, tpic_box},
  191.     {tpic_black, tpic_medium, tpic_triangle},
  192.     {tpic_white, tpic_medium, tpic_hexagon},
  193.     {tpic_black, tpic_medium, tpic_hexagon},
  194.     {tpic_white, tpic_medium, tpic_doublecircle},
  195.     {tpic_white, tpic_medium, tpic_vercircle},
  196.     {tpic_white, tpic_medium, tpic_horcircle},
  197.     {tpic_white, tpic_medium, tpic_pluscircle},
  198.     {tpic_white, tpic_medium, tpic_timescircle},
  199.     {tpic_white, tpic_medium, tpic_starcircle},
  200.     {tpic_black, tpic_medium, tpic_doublecircle},
  201.     {tpic_white, tpic_medium, tpic_dotcircle},
  202.     {tpic_white, tpic_medium, tpic_diamondcircle},
  203.     {tpic_white, tpic_medium, tpic_boxcircle},
  204.     {tpic_white, tpic_medium, tpic_trianglecircle},
  205.     {tpic_white, tpic_medium, tpic_hexagoncircle},
  206.     {tpic_white, tpic_medium, tpic_plustimescircle}
  207. };
  208.  
  209. typedef enum {tpic_solid, tpic_dotted, tpic_dashed, 
  210.     tpic_dashed_sdot, tpic_dashed_ddot} tpic_linestyle;
  211. typedef struct {
  212.     tpic_size thickness, interval;
  213.     tpic_linestyle linestyle;
  214. } tpic_line_info;
  215.  
  216. /* LINES */
  217. static GPFAR tpic_line_info GPFAR tpic_line[] = {
  218.     {tpic_medium, tpic_nosize, tpic_solid},  /* -2 border */
  219.     {tpic_small,  tpic_small,  tpic_dashed}, /* -1 axes */
  220.     {tpic_small,  tpic_nosize, tpic_solid},
  221.     {tpic_medium, tpic_nosize, tpic_solid},
  222.     {tpic_large,  tpic_nosize, tpic_solid},
  223.     {tpic_small,  tpic_small,  tpic_dotted},
  224.     {tpic_medium, tpic_small,  tpic_dotted},
  225.     {tpic_large,  tpic_small,  tpic_dotted},
  226.     {tpic_small,  tpic_small,  tpic_dashed},
  227.     {tpic_medium, tpic_small,  tpic_dashed},
  228.     {tpic_large,  tpic_small,  tpic_dashed},
  229.     {tpic_small,  tpic_small,  tpic_dashed_sdot}, /* dash with single dots */
  230.     {tpic_medium, tpic_small,  tpic_dashed_sdot},
  231.     {tpic_large,  tpic_small,  tpic_dashed_sdot},
  232.     {tpic_small,  tpic_small,  tpic_dashed_ddot}, /* dash with double dots */
  233.     {tpic_medium, tpic_small,  tpic_dashed_ddot},
  234.     {tpic_large,  tpic_small,  tpic_dashed_ddot},
  235.     {tpic_small,  tpic_medium, tpic_dotted},
  236.     {tpic_medium, tpic_medium, tpic_dotted},
  237.     {tpic_large,  tpic_medium, tpic_dotted},
  238.     {tpic_small,  tpic_medium, tpic_dashed},
  239.     {tpic_medium, tpic_medium, tpic_dashed},
  240.     {tpic_large,  tpic_medium, tpic_dashed},
  241.     {tpic_small,  tpic_medium, tpic_dashed_sdot},
  242.     {tpic_medium, tpic_medium, tpic_dashed_sdot},
  243.     {tpic_large,  tpic_medium, tpic_dashed_sdot},
  244.     {tpic_small,  tpic_medium, tpic_dashed_ddot},
  245.     {tpic_medium, tpic_medium, tpic_dashed_ddot},
  246.     {tpic_large,  tpic_medium, tpic_dashed_ddot},
  247.     {tpic_small,  tpic_large,  tpic_dotted},
  248.     {tpic_medium, tpic_large,  tpic_dotted},
  249.     {tpic_large,  tpic_large,  tpic_dotted},
  250.     {tpic_small,  tpic_large,  tpic_dashed},
  251.     {tpic_medium, tpic_large,  tpic_dashed},
  252.     {tpic_large,  tpic_large,  tpic_dashed},
  253.     {tpic_small,  tpic_large,  tpic_dashed_sdot},
  254.     {tpic_medium, tpic_large,  tpic_dashed_sdot},
  255.     {tpic_large,  tpic_large,  tpic_dashed_sdot},
  256.     {tpic_small,  tpic_large,  tpic_dashed_ddot},
  257.     {tpic_medium, tpic_large,  tpic_dashed_ddot},
  258.     {tpic_large,  tpic_large,  tpic_dashed_ddot}
  259. };
  260.  
  261. /* int TPIC_options(void) /* get size options */
  262. int TPIC_options() /* get size options */
  263. {
  264. /*
  265.     extern struct value *const_express(struct value *valptr);
  266.     extern double real(struct value *val);
  267.     */
  268.     extern struct value *const_express();
  269.     extern double real();
  270.     struct value a;
  271.     int pointsize, linewidth;
  272.     double interval;
  273.  
  274.     if (!END_OF_COMMAND) {
  275.         pointsize = (int)real(const_express(&a));
  276.         if (pointsize > 0) tpic_pointsize = pointsize;
  277.     }
  278.  
  279.     if (!END_OF_COMMAND) {
  280.         linewidth = (int)real(const_express(&a));
  281.         if (linewidth > 0) tpic_linewidth = linewidth;
  282.     }
  283.  
  284.     if (!END_OF_COMMAND) {
  285.         interval = (double)real(const_express(&a));
  286.         if (interval > 0) tpic_interval = interval;
  287.     }
  288.  
  289.     sprintf(term_options, "%d %d %f", tpic_pointsize, tpic_linewidth, 
  290.         tpic_interval);
  291.     return(0);
  292. }
  293.  
  294. static unsigned int tpic_posx; /* current position */
  295. static unsigned int tpic_posy;
  296. static int tpic_point_types;
  297. static int tpic_numlines;
  298.  
  299. /* int TPIC_init(void) */
  300. int TPIC_init()
  301. {
  302. static char GPFAR tpic1[] = "\
  303. %% GNUPLOT: LaTeX picture using tpic \\specials\n\
  304. %%          with %d point types and %d line types\n\
  305. %% Options: pointsize = %d, linewidth = %d, interval = %f\n\
  306. %% To change above options, say:\n\
  307. %% set terminal tpic pointsize_value linewidth_value interval_value\n\
  308. %% (pointsize and linewidth - integers in milli-inches.\n\
  309. %%  interval - a float in inches.  If zero is specified, \n\
  310. %%  the default value is chosen.)\n\
  311. \\setlength{\\unitlength}{%fin}%%\n";
  312.     tpic_point_types = sizeof(tpic_point) / sizeof(tpic_point[0]);
  313.     tpic_numlines = sizeof(tpic_line) / sizeof(tpic_line[0]);
  314.  
  315.     tpic_posx = tpic_posy = 0;
  316.     TPIC_linetype(-1);
  317.     fprintf(outfile, tpic1,
  318.         tpic_point_types, tpic_numlines - 2,
  319.         tpic_pointsize, tpic_linewidth, tpic_interval,
  320.         TPIC_UNIT);
  321.     return(0);
  322. }
  323.  
  324. /* int TPIC_reset(void) */
  325. int TPIC_reset()
  326. {
  327.     tpic_endline();
  328.     tpic_posx = tpic_posy = 0;
  329.     return(0);
  330. }
  331.  
  332. /* int TPIC_text(void) */
  333. int TPIC_text()
  334. {
  335.     tpic_endline();
  336.     fprintf(outfile, "\\end{picture}\n");
  337.     return(0);
  338. }
  339.  
  340. /* TBOOLEAN TPIC_scale(double xs, double ys) /* scaling factors */
  341. TBOOLEAN TPIC_scale(xs,ys)
  342. double xs; double ys; /* scaling factors */
  343. {
  344.     register struct termentry *t = &term_tbl[term];
  345.  
  346.     /* we change the table for use in graphics.c and TPIC_graphics */
  347.     t->xmax = (unsigned int)(TPIC_XMAX * xs);
  348.     t->ymax = (unsigned int)(TPIC_YMAX * ys);
  349.     return(TRUE);
  350. }
  351.  
  352. /* int TPIC_graphics(void) */
  353. int TPIC_graphics()
  354. {
  355.     register struct termentry *t = &term_tbl[term];
  356.     int left, right, top, bottom; /* margins */
  357.     static char GPFAR begin[] = "%s\\begin{picture}(%d,%d)(%d,%d)%% %s\n";
  358.  
  359.     fprintf(outfile, begin, "", t->xmax, t->ymax, 0, 0, "");
  360.  
  361.     /* the following is dependent on boundary() function in graphics.c */
  362.     left = TPIC_HCHAR * 12;
  363.     right = TPIC_HCHAR * 2 + TPIC_HTIC;
  364.     bottom = TPIC_VCHAR * 7 / 2 + 1;
  365.     top = TPIC_VCHAR * 5 / 2 - 1;
  366.     fprintf(outfile, begin, "%% ", t->xmax - left, t->ymax, left, 0, 
  367.         "trim left margin");
  368.     fprintf(outfile, begin, "%% ", t->xmax - right, t->ymax, 0, 0, 
  369.         "trim right margin");
  370.     fprintf(outfile, begin, "%% ", t->xmax - left - right, t->ymax, left, 0, 
  371.         "trim left & right margins");
  372.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - top, 0, 0, 
  373.         "trim top margin");
  374.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - bottom, 0, bottom, 
  375.         "trim bottom margin");
  376.     fprintf(outfile, begin, "%% ", t->xmax, t->ymax - top - bottom, 0, bottom,
  377.         "trim top & bottom margins");
  378.  
  379.     fprintf(outfile, "\\tenrm%%\n");
  380.     return(0);
  381. }
  382.  
  383. /* int TPIC_move(unsigned int x, unsigned int y) */
  384. int TPIC_move(x,y)
  385. unsigned int x; unsigned int y;
  386. {
  387.     tpic_endline();
  388.     tpic_posx = x;
  389.     tpic_posy = y;
  390.     return(0);
  391. }
  392.  
  393. #define TPIC_LINEMAX 100 /* max value for linecount */
  394. static TBOOLEAN tpic_inline = FALSE; /* are we in the middle of a line */
  395. static int tpic_linecount = 0; /* number of points in line so far */
  396.  
  397. /* int TPIC_vector(unsigned int ux, unsigned int uy) */
  398. int TPIC_vector(ux,uy)
  399. unsigned int ux; unsigned int uy;
  400. {
  401.     if (!tpic_inline) {
  402.         tpic_startline();
  403.     } else if (tpic_linecount >= TPIC_LINEMAX) {
  404.         /* Even though we are in middle of a path, we may start a new path 
  405.         command once in a while; if they are too long, latex will choke. */
  406.         tpic_endline();
  407.         tpic_startline();
  408.     }
  409.     tpic_pushpath(ux, uy);
  410.     tpic_posx = ux;
  411.     tpic_posy = uy;
  412.     return(0);
  413. }
  414.  
  415. static int tpic_linetype; /* current line type */
  416.  
  417. /* static void tpic_startline(void) /* private */
  418. static void tpic_startline() /* private */
  419. {
  420.     int thickness;
  421.  
  422.     tpic_inline = TRUE;
  423.     switch (tpic_line[tpic_linetype + 2].thickness) {
  424.     case tpic_small:
  425.         thickness = tpic_linewidth;
  426.         break;
  427.     case tpic_medium:
  428.         thickness = (int)(tpic_linewidth * 3);
  429.         break;
  430.     case tpic_large:
  431.         thickness = (int)(tpic_linewidth * 5);
  432.         break;
  433.     }
  434.     tpic_pen(thickness);
  435.     tpic_linecount = 0;
  436.     tpic_pushpath(tpic_posx, tpic_posy);
  437.     return;
  438. }
  439.  
  440. /* static void tpic_endline(void) /* private */
  441. static void tpic_endline() /* private */
  442. {
  443.     double interval;
  444.  
  445.     if (tpic_inline) {
  446.         tpic_scanpath(); /* draw actually */
  447.         switch (tpic_line[tpic_linetype + 2].interval) {
  448.         case tpic_small:
  449.             interval = tpic_interval;
  450.             break;
  451.         case tpic_medium:
  452.             interval = tpic_interval * 2;
  453.             break;
  454.         case tpic_large:
  455.             interval = tpic_interval * 3;
  456.             break;
  457.         case tpic_nosize:
  458.             break;
  459.         }
  460.         switch (tpic_line[tpic_linetype + 2].linestyle) {
  461.         case tpic_solid:
  462.             tpic_flush();
  463.             break;
  464.         case tpic_dotted:
  465.             tpic_dottedflush(interval);
  466.             break;
  467.         case tpic_dashed:
  468.             tpic_dashedflush(interval);
  469.             break;
  470.         case tpic_dashed_sdot: /* dashed with single dots in between */
  471.             tpic_dashedflush(interval);
  472.             tpic_scanpath(); /* draw again */
  473.             tpic_dottedflush(interval / 2);
  474.             break;
  475.         case tpic_dashed_ddot: /* dashed with double dots in between */
  476.             tpic_dashedflush(interval);
  477.             tpic_scanpath(); /* draw again */
  478.             tpic_dottedflush(interval / 3);
  479.             break;
  480.         }
  481.         tpic_inline = FALSE;
  482.     }
  483.     return;
  484. }
  485.  
  486. /* private: stack functions */
  487. static unsigned int pathpoint[TPIC_LINEMAX][2]; /* point stack */
  488.  
  489. /* static void tpic_pushpath(unsigned int x, unsigned int y) /* private */
  490. static void tpic_pushpath(x,y)
  491. unsigned int x; unsigned int y; /* private */
  492. {
  493.     if (tpic_linecount < TPIC_LINEMAX) {
  494.         pathpoint[tpic_linecount][0] = x;
  495.         pathpoint[tpic_linecount][1] = y;
  496.         tpic_linecount++;
  497.     }
  498.     return;
  499. }
  500.  
  501. /* static void tpic_scanpath(void) */
  502. static void tpic_scanpath()
  503. {
  504.     int i;
  505.  
  506.     for (i = 0; i < tpic_linecount; i++)
  507.         tpic_abspath(pathpoint[i][0], pathpoint[i][1]);
  508.     return;
  509. }
  510.  
  511. /* int TPIC_linetype(int linetype) */
  512. int TPIC_linetype(linetype)
  513. int linetype;
  514. {
  515.     tpic_endline();
  516.     if (linetype >= tpic_numlines - 2) linetype %= (tpic_numlines - 2);
  517.     tpic_linetype = linetype;
  518.     return(0);
  519. }
  520.  
  521. static int tpic_angle = 0; /* 0 = horizontal, 1 = vertical */
  522. static enum JUSTIFY tpic_justify = LEFT;
  523.  
  524. /* int TPIC_put_text(int x, int y, char *str) /* ref point and text */
  525. int TPIC_put_text(x,y,str)
  526. int x; int y; char *str; /* ref point and text */
  527. {
  528.     char *justify;
  529.  
  530.     tpic_endline();
  531.     fprintf(outfile, "\\put(%d,%d)", x, y);
  532.  
  533.     switch (tpic_angle) {
  534.     case 0: /* horizontal */
  535.         switch (tpic_justify) {
  536.         case LEFT:
  537.             justify = "[l]";
  538.             break;
  539.         case CENTRE:
  540.             justify = "";
  541.             break;
  542.         case RIGHT:
  543.             justify = "[r]";
  544.             break;
  545.         }
  546.         fprintf(outfile, "{\\makebox(0,0)%s{%s}}\n", justify, str);
  547.         break;
  548.     case 1: /* vertical */
  549.         /* we can't really write text vertically, but will put the ylabel 
  550.         centred at the left of the plot, and then we'll make a \shortstack */
  551.         switch (tpic_justify) {
  552.         case LEFT:
  553.             justify = "[lb]";
  554.             break;
  555.         case CENTRE:
  556.             justify = "[l]";
  557.             break;
  558.         case RIGHT:
  559.             justify = "[lt]";
  560.             break;
  561.         }
  562.         fprintf(outfile, "{\\makebox(0,0)%s{\\shortstack{%s}}}\n", 
  563.             justify, str);
  564.         break;
  565.     }
  566.     return(0);
  567. }
  568.  
  569. /* TBOOLEAN TPIC_text_angle(int angle) */
  570. TBOOLEAN TPIC_text_angle(angle)
  571. int angle;
  572. {
  573.     tpic_angle = angle;
  574.     return(TRUE);
  575. }
  576.  
  577. /* TBOOLEAN TPIC_justify_text(enum JUSTIFY mode) */
  578. TBOOLEAN TPIC_justify_text(mode)
  579. enum JUSTIFY mode;
  580. {
  581.     tpic_justify = mode;
  582.     return(TRUE);
  583. }
  584.  
  585. /* int TPIC_point(unsigned int x, unsigned int y, int number) */
  586. int TPIC_point(x,y,number)
  587. unsigned int x; unsigned int y; int number;
  588. {
  589.     int size;
  590.  
  591.     TPIC_move(x, y);
  592.  
  593.     /* Print the character defined by 'number'; number < 0 means 
  594.     to use a dot, otherwise one of the defined points. */
  595.  
  596.     fprintf(outfile, "\\put(%d,%d){", x, y); /* start putting */
  597.  
  598.     if (number < 0) {
  599.         fprintf(outfile, "\\rule{.1pt}{.1pt}"); /* tiny dot */
  600.     } else {
  601.         number %= tpic_point_types;
  602.         switch (tpic_point[number].shadestyle) {
  603.         case tpic_white:
  604.             tpic_pen(tpic_linewidth); /* set it thin */
  605.             tpic_shade(0.0);
  606.             break;
  607.         case tpic_gray:
  608.             tpic_pen(tpic_linewidth);
  609.             tpic_shade(0.5);
  610.             break;
  611.         case tpic_black:
  612.             tpic_pen(tpic_linewidth);
  613.             tpic_shade(1.0);
  614.             break;
  615.         case tpic_none:
  616.             tpic_pen(tpic_linewidth * 3); /* set it thick */
  617.             break;
  618.         }
  619.         switch (tpic_point[number].size) {
  620.         case tpic_small:
  621.             size = tpic_pointsize;
  622.             break;
  623.         case tpic_medium:
  624.             size = (int)(tpic_pointsize * 1.4142);
  625.             break;
  626.         case tpic_large:
  627.             size = (int)(tpic_pointsize * 2.0);
  628.             break;
  629.         }
  630.         (tpic_point[number].function)(size);
  631.     }
  632.  
  633.     fprintf(outfile, "}%%\n"); /* end putting */
  634.     return(0);
  635. }
  636.  
  637. /* int TPIC_arrow(int sx, int sy, int ex, int ey, TBOOLEAN head) */
  638. int TPIC_arrow(sx,sy,ex,ey,head)
  639. int sx; int sy; int ex; int ey; TBOOLEAN head;
  640. {
  641.     best_latex_arrow(sx, sy, ex, ey, 1, head); /* call latex routine */
  642.     tpic_posx = ex;
  643.     tpic_posy = ey;
  644.     return(0);
  645. }
  646.  
  647. /* private: draw points with tpic commands */
  648.  
  649. /* void tpic_diamond(int size) */
  650. void tpic_diamond(size)
  651. int size;
  652. {
  653.     size = (int)(size * 1.4142); /* spread by sqrt(2) */
  654.  
  655.     tpic_path(0, size);
  656.     tpic_path(-size, 0);
  657.     tpic_path(0, -size);
  658.     tpic_path(size, 0);
  659.     tpic_path(0, size);
  660.     tpic_flush();
  661.     return;
  662. }
  663.  
  664. /* void tpic_plus(int size) */
  665. void tpic_plus(size)
  666. int size;
  667. {
  668.     tpic_path(0, size);
  669.     tpic_path(0, -size);
  670.     tpic_flush();
  671.     tpic_path(size, 0);
  672.     tpic_path(-size, 0);
  673.     tpic_flush();
  674.     return;
  675. }
  676.  
  677. /* void tpic_box(int size) */
  678. void tpic_box(size)
  679. int size;
  680. {
  681.     tpic_path(size, size);
  682.     tpic_path(-size, size);
  683.     tpic_path(-size, -size);
  684.     tpic_path(size, -size);
  685.     tpic_path(size, size);
  686.     tpic_flush();
  687.     return;
  688. }
  689.  
  690. /* void tpic_times(int size) */
  691. void tpic_times(size)
  692. int size;
  693. {
  694.     size = (int)(size / 1.4142); /* reduce by sqrt(2) */
  695.  
  696.     tpic_path(size, size);
  697.     tpic_path(-size, -size);
  698.     tpic_flush();
  699.     tpic_path(size, -size);
  700.     tpic_path(-size, size);
  701.     tpic_flush();
  702.     return;
  703. }
  704.  
  705. /* void tpic_triangle(int size) */
  706. void tpic_triangle(size)
  707. int size;
  708. {
  709.     int x;
  710.  
  711.     size = (int)(size / 1.6119); /* reduce by sqrt(3 * sqrt(3) / 2) */
  712.     x = (int)(size * 1.7321);
  713.  
  714.     tpic_path(0, -size * 2);
  715.     tpic_path(-x, size);
  716.     tpic_path(x, size);
  717.     tpic_path(0, -size * 2);
  718.     tpic_flush();
  719.     return;
  720. }
  721.  
  722. /* void tpic_star(int size) */
  723. void tpic_star(size)
  724. int size;
  725. {
  726.     int x;
  727.  
  728.     size = (int)(size / 2); /* reduce by 2 */
  729.     x = (int)(size * 1.7321);
  730.  
  731.     tpic_path(0, size * 2);
  732.     tpic_path(0, -size * 2);
  733.     tpic_flush();
  734.     tpic_path(x, size);
  735.     tpic_path(-x, -size);
  736.     tpic_flush();
  737.     tpic_path(x, -size);
  738.     tpic_path(-x, size);
  739.     tpic_flush();
  740.     return;
  741. }
  742.  
  743. /* void tpic_hexagon(int size) */
  744. void tpic_hexagon(size)
  745. int size;
  746. {
  747.     int x;
  748.  
  749.     size = (int)(size / 2); /* reduce by 2 */
  750.     x = (int)(size * 1.7321);
  751.  
  752.     tpic_path(0, size * 2);
  753.     tpic_path(-x, size);
  754.     tpic_path(-x, -size);
  755.     tpic_path(0, -size * 2);
  756.     tpic_path(x, -size);
  757.     tpic_path(x, size);
  758.     tpic_path(0, size * 2);
  759.     tpic_flush();
  760.     return;
  761. }
  762.  
  763. /* void tpic_circle(int size) */
  764. void tpic_circle(size)
  765. int size;
  766. {
  767.     tpic_arc(size);
  768.     return;
  769. }
  770.  
  771. /* void tpic_doublecircle(int size) */
  772. void tpic_doublecircle(size)
  773. int size;
  774. {
  775.     tpic_arc(size);
  776.     tpic_shade(0.0);
  777.     tpic_arc(size / 2);
  778.     return;
  779. }
  780.  
  781. /* void tpic_vercircle(int size) /* circle with | */
  782. void tpic_vercircle(size)
  783. int size; /* circle with | */
  784. {
  785.     tpic_arc(size);
  786.     tpic_path(0, size);
  787.     tpic_path(0, -size);
  788.     tpic_flush();
  789.     return;
  790. }
  791.  
  792. /* void tpic_horcircle(int size) /* circle with - */
  793. void tpic_horcircle(size)
  794. int size; /* circle with - */
  795. {
  796.     tpic_arc(size);
  797.     tpic_path(size, 0);
  798.     tpic_path(-size, 0);
  799.     tpic_flush();
  800.     return;
  801. }
  802.  
  803. /* void tpic_pluscircle(int size) /* circle with + */
  804. void tpic_pluscircle(size)
  805. int size; /* circle with + */
  806. {
  807.     tpic_arc(size);
  808.     tpic_plus(size);
  809.     return;
  810. }
  811.  
  812. /* void tpic_timescircle(int size) /* circle with times */
  813. void tpic_timescircle(size)
  814. int size; /* circle with times */
  815. {
  816.     tpic_arc(size);
  817.     tpic_times(size);
  818.     return;
  819. }
  820.  
  821. /* void tpic_starcircle(int size) /* circle with star */
  822. void tpic_starcircle(size)
  823. int size; /* circle with star */
  824. {
  825.     tpic_arc(size);
  826.     tpic_star(size);
  827.     return;
  828. }
  829.  
  830. /* void tpic_dotcircle(int size) /* circle with dot (black circle) */
  831. void tpic_dotcircle(size)
  832. int size; /* circle with dot (black circle) */
  833. {
  834.     tpic_arc(size);
  835.     tpic_shade(1.0);
  836.     tpic_arc(size / 2);
  837.     return;
  838. }
  839.  
  840. /* void tpic_diamondcircle(int size) /* not enough? circle with black diamond */
  841. void tpic_diamondcircle(size)
  842. int size; /* not enough? circle with black diamond */
  843. {
  844.     tpic_arc(size);
  845.     tpic_shade(1.0);
  846.     tpic_diamond((int)(size / 1.5));
  847.     return;
  848. }
  849.  
  850. /* void tpic_boxcircle(int size) /* need more? circle with black box */
  851. void tpic_boxcircle(size)
  852. int size; /* need more? circle with black box */
  853. {
  854.     tpic_arc(size);
  855.     tpic_shade(1.0);
  856.     tpic_box((int)(size / 1.5));
  857.     return;
  858. }
  859.  
  860. /* void tpic_trianglecircle(int size) /* circle with black triangle */
  861. void tpic_trianglecircle(size)
  862. int size; /* circle with black triangle */
  863. {
  864.     tpic_arc(size);
  865.     tpic_shade(1.0);
  866.     tpic_triangle((int)(size / 1.5));
  867.     return;
  868. }
  869.  
  870. /* void tpic_hexagoncircle(int size) /* how about circle with black hexagon? */
  871. void tpic_hexagoncircle(size)
  872. int size; /* how about circle with black hexagon? */
  873. {
  874.     tpic_arc(size);
  875.     tpic_shade(1.0);
  876.     tpic_hexagon((int)(size / 1.2));
  877.     return;
  878. }
  879.  
  880. /* void tpic_plustimescircle(int size) /* no more idea ... with plus & times */
  881. void tpic_plustimescircle(size)
  882. int size; /* no more idea ... with plus & times */
  883. {
  884.     tpic_arc(size);
  885.     tpic_plus(size);
  886.     tpic_times(size);
  887.     return;
  888. }
  889.  
  890. /* private: draw lines */
  891.  
  892. /* void tpic_abspath(unsigned int x, unsigned int y) /* absolute coord */
  893. void tpic_abspath(x,y)
  894. unsigned int x; unsigned int y; /* absolute coord */
  895. {
  896.     fprintf(outfile, "\\put(%u,%u){", x, y); /* start putting */
  897.     tpic_path(0, 0);
  898.     fprintf(outfile, "}%%\n"); /* end putting */
  899.     return;
  900. }
  901.  
  902. /* private: tpic primitive functions */
  903.  
  904. /* void tpic_path(int x, int y) */
  905. void tpic_path(x,y)
  906. int x; int y;
  907. {
  908.     fprintf(outfile, "\\special{pa %d %d}", x, y);
  909.     return;
  910. }
  911.  
  912. /* void tpic_flush(void) */
  913. void tpic_flush()
  914. {
  915.     fprintf(outfile, "\\special{fp}%%\n");
  916.     return;
  917. }
  918.  
  919. /* void tpic_arc(int radius) /* actually, draw a full circle */
  920. void tpic_arc(radius)
  921. int radius; /* actually, draw a full circle */
  922. {
  923.     fprintf(outfile, "\\special{ar 0 0 %d %d 0 7}", radius, radius);
  924.     return;
  925. }
  926.  
  927. /* void tpic_shade(double grayscale) */
  928. void tpic_shade(grayscale)
  929. double grayscale;
  930. {
  931.     fprintf(outfile, "\\special{sh %f}", grayscale);
  932.     return;
  933. }
  934.  
  935. /* void tpic_pen(int thickness) */
  936. void tpic_pen(thickness)
  937. int thickness;
  938. {
  939.     fprintf(outfile, "\\special{pn %d}", thickness);
  940.     return;
  941. }
  942.  
  943. /* void tpic_dottedflush(double interval) */
  944. void tpic_dottedflush(interval)
  945. double interval;
  946. {
  947.     fprintf(outfile, "\\special{dt %f}%%\n", interval);
  948.     return;
  949. }
  950.  
  951. /* void tpic_dashedflush(double interval) */
  952. void tpic_dashedflush(interval)
  953. double interval;
  954. {
  955.     fprintf(outfile, "\\special{da %f}%%\n", interval);
  956.     return;
  957. }
  958.